<!DOCTYPE html>
<html lang="en-US">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="language" content="en" />
        <link href="./assets/ffd55088/css/bootstrap.css" rel="stylesheet">
<link href="./assets/5cf9384a/solarized_light.css" rel="stylesheet">
<link href="./assets/6c54116e/style.css" rel="stylesheet">
<script src="./assets/a44cef0f/jquery.js"></script>
<script src="./assets/ffd55088/js/bootstrap.js"></script>
<script src="./assets/8ac4e28a/jssearch.js"></script>    <title>Events - Key Concepts - The Definitive Guide to Yii 2.0</title>
</head>
<body>

<div class="wrap">
    <nav id="w1422" class="navbar-inverse navbar-fixed-top navbar" role="navigation"><div class="navbar-header"><button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#w1422-collapse"><span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span></button><a class="navbar-brand" href="./index.html">The Definitive Guide to Yii 2.0</a></div><div id="w1422-collapse" class="collapse navbar-collapse"><ul id="w1423" class="navbar-nav nav"><li><a href="./index.html">Class reference</a></li>
<li class="dropdown"><a class="dropdown-toggle" href="#" data-toggle="dropdown">Extensions <b class="caret"></b></a><ul id="w1424" class="dropdown-menu"><li><a href="./ext-apidoc-index.html" tabindex="-1">apidoc</a></li>
<li><a href="./ext-authclient-index.html" tabindex="-1">authclient</a></li>
<li><a href="./ext-bootstrap-index.html" tabindex="-1">bootstrap</a></li>
<li><a href="./ext-codeception-index.html" tabindex="-1">codeception</a></li>
<li><a href="./ext-debug-index.html" tabindex="-1">debug</a></li>
<li><a href="./ext-elasticsearch-index.html" tabindex="-1">elasticsearch</a></li>
<li><a href="./ext-faker-index.html" tabindex="-1">faker</a></li>
<li><a href="./ext-gii-index.html" tabindex="-1">gii</a></li>
<li><a href="./ext-imagine-index.html" tabindex="-1">imagine</a></li>
<li><a href="./ext-jui-index.html" tabindex="-1">jui</a></li>
<li><a href="./ext-mongodb-index.html" tabindex="-1">mongodb</a></li>
<li><a href="./ext-redis-index.html" tabindex="-1">redis</a></li>
<li><a href="./ext-smarty-index.html" tabindex="-1">smarty</a></li>
<li><a href="./ext-sphinx-index.html" tabindex="-1">sphinx</a></li>
<li><a href="./ext-swiftmailer-index.html" tabindex="-1">swiftmailer</a></li>
<li><a href="./ext-twig-index.html" tabindex="-1">twig</a></li></ul></li>
<li><a href="./guide-README.html">Guide</a></li></ul><div class="navbar-form navbar-left" role="search">
  <div class="form-group">
    <input id="searchbox" type="text" class="form-control" placeholder="Search">
  </div>
</div>
</div></nav>
    <div id="search-resultbox" style="display: none;" class="modal-content">
        <ul id="search-results">
        </ul>
    </div>

    
<div class="row">
    <div class="col-md-2">
                <div id="navigation" class="list-group"><a class="list-group-item" href="#navigation-1406" data-toggle="collapse" data-parent="#navigation">Introduction <b class="caret"></b></a><div id="navigation-1406" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-intro-yii.html">About Yii</a>
<a class="list-group-item" href="./guide-intro-upgrade-from-v1.html">Upgrading from Version 1.1</a></div>
<a class="list-group-item" href="#navigation-1407" data-toggle="collapse" data-parent="#navigation">Getting Started <b class="caret"></b></a><div id="navigation-1407" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-start-installation.html">Installing Yii</a>
<a class="list-group-item" href="./guide-start-workflow.html">Running Applications</a>
<a class="list-group-item" href="./guide-start-hello.html">Saying Hello</a>
<a class="list-group-item" href="./guide-start-forms.html">Working with Forms</a>
<a class="list-group-item" href="./guide-start-databases.html">Working with Databases</a>
<a class="list-group-item" href="./guide-start-gii.html">Generating Code with Gii</a>
<a class="list-group-item" href="./guide-start-looking-ahead.html">Looking Ahead</a></div>
<a class="list-group-item" href="#navigation-1408" data-toggle="collapse" data-parent="#navigation">Application Structure <b class="caret"></b></a><div id="navigation-1408" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-structure-overview.html">Overview</a>
<a class="list-group-item" href="./guide-structure-entry-scripts.html">Entry Scripts</a>
<a class="list-group-item" href="./guide-structure-applications.html">Applications</a>
<a class="list-group-item" href="./guide-structure-application-components.html">Application Components</a>
<a class="list-group-item" href="./guide-structure-controllers.html">Controllers</a>
<a class="list-group-item" href="./guide-structure-models.html">Models</a>
<a class="list-group-item" href="./guide-structure-views.html">Views</a>
<a class="list-group-item" href="./guide-structure-modules.html">Modules</a>
<a class="list-group-item" href="./guide-structure-filters.html">Filters</a>
<a class="list-group-item" href="./guide-structure-widgets.html">Widgets</a>
<a class="list-group-item" href="./guide-structure-assets.html">Assets</a>
<a class="list-group-item" href="./guide-structure-extensions.html">Extensions</a></div>
<a class="list-group-item" href="#navigation-1409" data-toggle="collapse" data-parent="#navigation">Handling Requests <b class="caret"></b></a><div id="navigation-1409" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-runtime-overview.html">Overview</a>
<a class="list-group-item" href="./guide-runtime-bootstrapping.html">Bootstrapping</a>
<a class="list-group-item" href="./guide-runtime-routing.html">Routing and URL Creation</a>
<a class="list-group-item" href="./guide-runtime-requests.html">Requests</a>
<a class="list-group-item" href="./guide-runtime-responses.html">Responses</a>
<a class="list-group-item" href="./guide-runtime-sessions-cookies.html">Sessions and Cookies</a>
<a class="list-group-item" href="./guide-runtime-handling-errors.html">Handling Errors</a>
<a class="list-group-item" href="./guide-runtime-logging.html">Logging</a></div>
<a class="list-group-item active" href="#navigation-1410" data-toggle="collapse" data-parent="#navigation">Key Concepts <b class="caret"></b></a><div id="navigation-1410" class="submenu panel-collapse collapse in"><a class="list-group-item" href="./guide-concept-components.html">Components</a>
<a class="list-group-item" href="./guide-concept-properties.html">Properties</a>
<a class="list-group-item active" href="./guide-concept-events.html">Events</a>
<a class="list-group-item" href="./guide-concept-behaviors.html">Behaviors</a>
<a class="list-group-item" href="./guide-concept-configurations.html">Configurations</a>
<a class="list-group-item" href="./guide-concept-aliases.html">Aliases</a>
<a class="list-group-item" href="./guide-concept-autoloading.html">Class Autoloading</a>
<a class="list-group-item" href="./guide-concept-service-locator.html">Service Locator</a>
<a class="list-group-item" href="./guide-concept-di-container.html">Dependency Injection Container</a></div>
<a class="list-group-item" href="#navigation-1411" data-toggle="collapse" data-parent="#navigation">Working with Databases <b class="caret"></b></a><div id="navigation-1411" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-db-dao.html">Data Access Objects</a>
<a class="list-group-item" href="./guide-db-query-builder.html">Query Builder</a>
<a class="list-group-item" href="./guide-db-active-record.html">Active Record</a>
<a class="list-group-item" href="./guide-db-migrations.html">Migrations</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-sphinx/blob/master/docs/guide/README.md">Sphinx</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-redis/blob/master/docs/guide/README.md">Redis</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-mongodb/blob/master/docs/guide/README.md">MongoDB</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-elasticsearch/blob/master/docs/guide/README.md">ElasticSearch</a></div>
<a class="list-group-item" href="#navigation-1412" data-toggle="collapse" data-parent="#navigation">Getting Data from Users <b class="caret"></b></a><div id="navigation-1412" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-input-forms.html">Creating Forms</a>
<a class="list-group-item" href="./guide-input-validation.html">Validating Input</a>
<a class="list-group-item" href="./guide-input-file-upload.html">Uploading Files</a>
<a class="list-group-item" href="./guide-input-tabular-input.html">Collecting Tabular Input</a>
<a class="list-group-item" href="./guide-input-multiple-models.html">Getting Data for Multiple Models</a></div>
<a class="list-group-item" href="#navigation-1413" data-toggle="collapse" data-parent="#navigation">Displaying Data <b class="caret"></b></a><div id="navigation-1413" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-output-formatting.html">Data Formatting</a>
<a class="list-group-item" href="./guide-output-pagination.html">Pagination</a>
<a class="list-group-item" href="./guide-output-sorting.html">Sorting</a>
<a class="list-group-item" href="./guide-output-data-providers.html">Data Providers</a>
<a class="list-group-item" href="./guide-output-data-widgets.html">Data Widgets</a>
<a class="list-group-item" href="./guide-output-client-scripts.html">Working with Client Scripts</a>
<a class="list-group-item" href="./guide-output-theming.html">Theming</a></div>
<a class="list-group-item" href="#navigation-1414" data-toggle="collapse" data-parent="#navigation">Security <b class="caret"></b></a><div id="navigation-1414" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-security-overview.html">Overview</a>
<a class="list-group-item" href="./guide-security-authentication.html">Authentication</a>
<a class="list-group-item" href="./guide-security-authorization.html">Authorization</a>
<a class="list-group-item" href="./guide-security-passwords.html">Working with Passwords</a>
<a class="list-group-item" href="./guide-security-cryptography.html">Cryptography</a>
<a class="list-group-item" href="./guide-structure-views.html#security">Views security</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-authclient/blob/master/docs/guide/README.md">Auth Clients</a>
<a class="list-group-item" href="./guide-security-best-practices.html">Best Practices</a></div>
<a class="list-group-item" href="#navigation-1415" data-toggle="collapse" data-parent="#navigation">Caching <b class="caret"></b></a><div id="navigation-1415" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-caching-overview.html">Overview</a>
<a class="list-group-item" href="./guide-caching-data.html">Data Caching</a>
<a class="list-group-item" href="./guide-caching-fragment.html">Fragment Caching</a>
<a class="list-group-item" href="./guide-caching-page.html">Page Caching</a>
<a class="list-group-item" href="./guide-caching-http.html">HTTP Caching</a></div>
<a class="list-group-item" href="#navigation-1416" data-toggle="collapse" data-parent="#navigation">RESTful Web Services <b class="caret"></b></a><div id="navigation-1416" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-rest-quick-start.html">Quick Start</a>
<a class="list-group-item" href="./guide-rest-resources.html">Resources</a>
<a class="list-group-item" href="./guide-rest-controllers.html">Controllers</a>
<a class="list-group-item" href="./guide-rest-routing.html">Routing</a>
<a class="list-group-item" href="./guide-rest-response-formatting.html">Response Formatting</a>
<a class="list-group-item" href="./guide-rest-authentication.html">Authentication</a>
<a class="list-group-item" href="./guide-rest-rate-limiting.html">Rate Limiting</a>
<a class="list-group-item" href="./guide-rest-versioning.html">Versioning</a>
<a class="list-group-item" href="./guide-rest-error-handling.html">Error Handling</a></div>
<a class="list-group-item" href="#navigation-1417" data-toggle="collapse" data-parent="#navigation">Development Tools <b class="caret"></b></a><div id="navigation-1417" class="submenu panel-collapse collapse"><a class="list-group-item" href="https://github.com/yiisoft/yii2-debug/blob/master/docs/guide/README.md">Debug Toolbar and Debugger</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-gii/blob/master/docs/guide/README.md">Generating Code using Gii</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-apidoc">Generating API Documentation</a></div>
<a class="list-group-item" href="#navigation-1418" data-toggle="collapse" data-parent="#navigation">Testing <b class="caret"></b></a><div id="navigation-1418" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-test-overview.html">Overview</a>
<a class="list-group-item" href="./guide-test-environment-setup.html">Testing environment setup</a>
<a class="list-group-item" href="./guide-test-unit.html">Unit Tests</a>
<a class="list-group-item" href="./guide-test-functional.html">Functional Tests</a>
<a class="list-group-item" href="./guide-test-acceptance.html">Acceptance Tests</a>
<a class="list-group-item" href="./guide-test-fixtures.html">Fixtures</a></div>
<a class="list-group-item" href="#navigation-1419" data-toggle="collapse" data-parent="#navigation">Special Topics <b class="caret"></b></a><div id="navigation-1419" class="submenu panel-collapse collapse"><a class="list-group-item" href="https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/README.md">Advanced Project Template</a>
<a class="list-group-item" href="./guide-tutorial-start-from-scratch.html">Building Application from Scratch</a>
<a class="list-group-item" href="./guide-tutorial-console.html">Console Commands</a>
<a class="list-group-item" href="./guide-tutorial-core-validators.html">Core Validators</a>
<a class="list-group-item" href="./guide-tutorial-i18n.html">Internationalization</a>
<a class="list-group-item" href="./guide-tutorial-mailing.html">Mailing</a>
<a class="list-group-item" href="./guide-tutorial-performance-tuning.html">Performance Tuning</a>
<a class="list-group-item" href="./guide-tutorial-shared-hosting.html">Shared Hosting Environment</a>
<a class="list-group-item" href="./guide-tutorial-template-engines.html">Template Engines</a>
<a class="list-group-item" href="./guide-tutorial-yii-integration.html">Working with Third-Party Code</a></div>
<a class="list-group-item" href="#navigation-1420" data-toggle="collapse" data-parent="#navigation">Widgets <b class="caret"></b></a><div id="navigation-1420" class="submenu panel-collapse collapse"><a class="list-group-item" href="https://github.com/yiisoft/yii2-bootstrap/blob/master/docs/guide/README.md">Bootstrap Widgets</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-jui/blob/master/docs/guide/README.md">jQuery UI Widgets</a></div>
<a class="list-group-item" href="#navigation-1421" data-toggle="collapse" data-parent="#navigation">Helpers <b class="caret"></b></a><div id="navigation-1421" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-helper-overview.html">Overview</a>
<a class="list-group-item" href="./guide-helper-array.html">ArrayHelper</a>
<a class="list-group-item" href="./guide-helper-html.html">Html</a>
<a class="list-group-item" href="./guide-helper-url.html">Url</a></div></div>    </div>
    <div class="col-md-9 guide-content" role="main">
        <h1>Events <span id="events"></span><a href="#events" class="hashlink">&para;</a></h1>
<div class="toc"><ol><li><a href="#event-handlers">Event Handlers</a></li>
<li><a href="#attaching-event-handlers">Attaching Event Handlers</a></li>
<li><a href="#event-handler-order">Event Handler Order</a></li>
<li><a href="#triggering-events">Triggering Events</a></li>
<li><a href="#detaching-event-handlers">Detaching Event Handlers</a></li>
<li><a href="#class-level-event-handlers">Class-Level Event Handlers</a></li>
<li><a href="#interface-level-event-handlers">Events using interfaces</a></li>
<li><a href="#global-events">Global Events</a></li></ol></div>
<p>Events allow you to inject custom code into existing code at certain execution points. You can attach custom
code to an event so that when the event is triggered, the code gets executed automatically. For example,
a mailer object may trigger a <code>messageSent</code> event when it successfully sends a message. If you want to keep
track of the messages that are successfully sent, you could then simply attach the tracking code to the <code>messageSent</code> event.</p>
<p>Yii introduces a base class called <a href="./yii-base-component.html">yii\base\Component</a> to support events. If a class needs to trigger
events, it should extend from <a href="./yii-base-component.html">yii\base\Component</a>, or from a child class.</p>
<h2>Event Handlers  <span id="event-handlers"></span><a href="#event-handlers" class="hashlink">&para;</a></h2><p>An event handler is a <a href="http://www.php.net/manual/en/language.types.callable.php">PHP callback</a> that gets executed
when the event it is attached to is triggered. You can use any of the following callbacks:</p>
<ul>
<li>a global PHP function specified as a string (without parentheses), e.g., <code>'trim'</code>;</li>
<li>an object method specified as an array of an object and a method name as a string (without parentheses), e.g., <code>[$object, 'methodName']</code>;</li>
<li>a static class method specified as an array of a class name and a method name as a string (without parentheses), e.g., <code>['ClassName', 'methodName']</code>;</li>
<li>an anonymous function, e.g., <code>function ($event) { ... }</code>.</li>
</ul>
<p>The signature of an event handler is:</p>
<pre><code class="hljs php language-php"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$event</span>)</span> </span>{
    <span class="hljs-comment">// $event is an object of yii\base\Event or a child class</span>
}
</code></pre>
<p>Through the <code>$event</code> parameter, an event handler may get the following information about the event that occurred:</p>
<ul>
<li><a href="./yii-base-event.html#$name-detail">event name</a></li>
<li><a href="./yii-base-event.html#$sender-detail">event sender</a>: the object whose <code>trigger()</code> method was called</li>
<li><a href="./yii-base-event.html#$data-detail">custom data</a>: the data that is provided when attaching the event handler (to be explained next)</li>
</ul>
<h2>Attaching Event Handlers  <span id="attaching-event-handlers"></span><a href="#attaching-event-handlers" class="hashlink">&para;</a></h2><p>You can attach a handler to an event by calling the <a href="./yii-base-component.html#on()-detail">yii\base\Component::on()</a> method. For example:</p>
<pre><code class="hljs php language-php"><span class="hljs-variable">$foo</span> = <span class="hljs-keyword">new</span> Foo;

<span class="hljs-comment">// this handler is a global function</span>
<span class="hljs-variable">$foo</span>-&gt;on(Foo::EVENT_HELLO, <span class="hljs-string">'function_name'</span>);

<span class="hljs-comment">// this handler is an object method</span>
<span class="hljs-variable">$foo</span>-&gt;on(Foo::EVENT_HELLO, [<span class="hljs-variable">$object</span>, <span class="hljs-string">'methodName'</span>]);

<span class="hljs-comment">// this handler is a static class method</span>
<span class="hljs-variable">$foo</span>-&gt;on(Foo::EVENT_HELLO, [<span class="hljs-string">'app\components\Bar'</span>, <span class="hljs-string">'methodName'</span>]);

<span class="hljs-comment">// this handler is an anonymous function</span>
<span class="hljs-variable">$foo</span>-&gt;on(Foo::EVENT_HELLO, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$event</span>)</span> </span>{
    <span class="hljs-comment">// event handling logic</span>
});
</code></pre>
<p>You may also attach event handlers through <a href="guide-concept-configurations.html">configurations</a>. For more details, please
refer to the <a href="guide-concept-configurations.html#configuration-format">Configurations</a> section.</p>
<p>When attaching an event handler, you may provide additional data as the third parameter to <a href="./yii-base-component.html#on()-detail">yii\base\Component::on()</a>.
The data will be made available to the handler when the event is triggered and the handler is called. For example:</p>
<pre><code class="hljs php language-php"><span class="hljs-comment">// The following code will display "abc" when the event is triggered</span>
<span class="hljs-comment">// because $event-&gt;data contains the data passed as the 3rd argument to "on"</span>
<span class="hljs-variable">$foo</span>-&gt;on(Foo::EVENT_HELLO, <span class="hljs-string">'function_name'</span>, <span class="hljs-string">'abc'</span>);

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">function_name</span><span class="hljs-params">(<span class="hljs-variable">$event</span>)</span> </span>{
    <span class="hljs-keyword">echo</span> <span class="hljs-variable">$event</span>-&gt;data;
}
</code></pre>
<h2>Event Handler Order <span id="event-handler-order"></span><a href="#event-handler-order" class="hashlink">&para;</a></h2><p>You may attach one or more handlers to a single event. When an event is triggered, the attached handlers
will be called in the order that they were attached to the event. If a handler needs to stop the invocation of the
handlers that follow it, it may set the <a href="./yii-base-event.html#$handled-detail">yii\base\Event::$handled</a> property of the <code>$event</code> parameter to be true:</p>
<pre><code class="hljs php language-php"><span class="hljs-variable">$foo</span>-&gt;on(Foo::EVENT_HELLO, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$event</span>)</span> </span>{
    <span class="hljs-variable">$event</span>-&gt;handled = <span class="hljs-keyword">true</span>;
});
</code></pre>
<p>By default, a newly attached handler is appended to the existing handler queue for the event.
As a result, the handler will be called in the last place when the event is triggered.
To insert the new handler at the start of the handler queue so that the handler gets called first, you may call <a href="./yii-base-component.html#on()-detail">yii\base\Component::on()</a>, passing false for the fourth parameter <code>$append</code>:</p>
<pre><code class="hljs php language-php"><span class="hljs-variable">$foo</span>-&gt;on(Foo::EVENT_HELLO, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$event</span>)</span> </span>{
    <span class="hljs-comment">// ...</span>
}, <span class="hljs-variable">$data</span>, <span class="hljs-keyword">false</span>);
</code></pre>
<h2>Triggering Events  <span id="triggering-events"></span><a href="#triggering-events" class="hashlink">&para;</a></h2><p>Events are triggered by calling the <a href="./yii-base-component.html#trigger()-detail">yii\base\Component::trigger()</a> method. The method requires an <em>event name</em>,
and optionally an event object that describes the parameters to be passed to the event handlers. For example:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">namespace</span> <span class="hljs-title">app</span>\<span class="hljs-title">components</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">yii</span>\<span class="hljs-title">base</span>\<span class="hljs-title">Component</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">yii</span>\<span class="hljs-title">base</span>\<span class="hljs-title">Event</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Foo</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span>
</span>{
    <span class="hljs-keyword">const</span> EVENT_HELLO = <span class="hljs-string">'hello'</span>;

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bar</span><span class="hljs-params">()</span>
    </span>{
        <span class="hljs-variable">$this</span>-&gt;trigger(<span class="hljs-keyword">self</span>::EVENT_HELLO);
    }
}
</code></pre>
<p>With the above code, any calls to <code>bar()</code> will trigger an event named <code>hello</code>.</p>
<blockquote class="tip"><p><strong>Tip: </strong>It is recommended to use class constants to represent event names. In the above example, the constant
  <code>EVENT_HELLO</code> represents the <code>hello</code> event. This approach has three benefits. First, it prevents typos. Second, it can make events recognizable for IDE
  auto-completion support. Third, you can tell what events are supported in a class by simply checking its constant declarations.</p>
</blockquote>
<p>Sometimes when triggering an event you may want to pass along additional information to the event handlers.
For example, a mailer may want pass the message information to the handlers of the <code>messageSent</code> event so that the handlers
can know the particulars of the sent messages. To do so, you can provide an event object as the second parameter to
the <a href="./yii-base-component.html#trigger()-detail">yii\base\Component::trigger()</a> method. The event object must be an instance of the <a href="./yii-base-event.html">yii\base\Event</a> class
or a child class. For example:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">namespace</span> <span class="hljs-title">app</span>\<span class="hljs-title">components</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">yii</span>\<span class="hljs-title">base</span>\<span class="hljs-title">Component</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">yii</span>\<span class="hljs-title">base</span>\<span class="hljs-title">Event</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MessageEvent</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Event</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-variable">$message</span>;
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Mailer</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span>
</span>{
    <span class="hljs-keyword">const</span> EVENT_MESSAGE_SENT = <span class="hljs-string">'messageSent'</span>;

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">send</span><span class="hljs-params">(<span class="hljs-variable">$message</span>)</span>
    </span>{
        <span class="hljs-comment">// ...sending $message...</span>

        <span class="hljs-variable">$event</span> = <span class="hljs-keyword">new</span> MessageEvent;
        <span class="hljs-variable">$event</span>-&gt;message = <span class="hljs-variable">$message</span>;
        <span class="hljs-variable">$this</span>-&gt;trigger(<span class="hljs-keyword">self</span>::EVENT_MESSAGE_SENT, <span class="hljs-variable">$event</span>);
    }
}
</code></pre>
<p>When the <a href="./yii-base-component.html#trigger()-detail">yii\base\Component::trigger()</a> method is called, it will call all handlers attached to
the named event.</p>
<h2>Detaching Event Handlers  <span id="detaching-event-handlers"></span><a href="#detaching-event-handlers" class="hashlink">&para;</a></h2><p>To detach a handler from an event, call the <a href="./yii-base-component.html#off()-detail">yii\base\Component::off()</a> method. For example:</p>
<pre><code class="hljs php language-php"><span class="hljs-comment">// the handler is a global function</span>
<span class="hljs-variable">$foo</span>-&gt;off(Foo::EVENT_HELLO, <span class="hljs-string">'function_name'</span>);

<span class="hljs-comment">// the handler is an object method</span>
<span class="hljs-variable">$foo</span>-&gt;off(Foo::EVENT_HELLO, [<span class="hljs-variable">$object</span>, <span class="hljs-string">'methodName'</span>]);

<span class="hljs-comment">// the handler is a static class method</span>
<span class="hljs-variable">$foo</span>-&gt;off(Foo::EVENT_HELLO, [<span class="hljs-string">'app\components\Bar'</span>, <span class="hljs-string">'methodName'</span>]);

<span class="hljs-comment">// the handler is an anonymous function</span>
<span class="hljs-variable">$foo</span>-&gt;off(Foo::EVENT_HELLO, <span class="hljs-variable">$anonymousFunction</span>);
</code></pre>
<p>Note that in general you should not try to detach an anonymous function unless you store it
somewhere when it is attached to the event. In the above example, it is assumed that the anonymous
function is stored as a variable <code>$anonymousFunction</code>.</p>
<p>To detach ALL handlers from an event, simply call <a href="./yii-base-component.html#off()-detail">yii\base\Component::off()</a> without the second parameter:</p>
<pre><code class="hljs php language-php"><span class="hljs-variable">$foo</span>-&gt;off(Foo::EVENT_HELLO);
</code></pre>
<h2>Class-Level Event Handlers  <span id="class-level-event-handlers"></span><a href="#class-level-event-handlers" class="hashlink">&para;</a></h2><p>The above subsections described how to attach a handler to an event on an <em>instance level</em>.
Sometimes, you may want to respond to an event triggered by <em>every</em> instance of a class instead of only by
a specific instance. Instead of attaching an event handler to every instance, you may attach the handler
on the <em>class level</em> by calling the static method <a href="./yii-base-event.html#on()-detail">yii\base\Event::on()</a>.</p>
<p>For example, an <a href="guide-db-active-record.html">Active Record</a> object will trigger an <a href="./yii-db-baseactiverecord.html#EVENT_AFTER_INSERT-detail">EVENT_AFTER_INSERT</a>
event whenever it inserts a new record into the database. In order to track insertions done by <em>every</em>
<a href="guide-db-active-record.html">Active Record</a> object, you may use the following code:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">use</span> <span class="hljs-title">Yii</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">yii</span>\<span class="hljs-title">base</span>\<span class="hljs-title">Event</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">yii</span>\<span class="hljs-title">db</span>\<span class="hljs-title">ActiveRecord</span>;

Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$event</span>)</span> </span>{
    Yii::trace(get_class(<span class="hljs-variable">$event</span>-&gt;sender) . <span class="hljs-string">' is inserted'</span>);
});
</code></pre>
<p>The event handler will be invoked whenever an instance of <a href="./yii-db-activerecord.html">ActiveRecord</a>, or one of its child classes, triggers
the <a href="./yii-db-baseactiverecord.html#EVENT_AFTER_INSERT-detail">EVENT_AFTER_INSERT</a> event. In the handler, you can get the object
that triggered the event through <code>$event-&gt;sender</code>.</p>
<p>When an object triggers an event, it will first call instance-level handlers, followed by the class-level handlers.</p>
<p>You may trigger a <em>class-level</em> event by calling the static method <a href="./yii-base-event.html#trigger()-detail">yii\base\Event::trigger()</a>. A class-level
event is not associated with a particular object. As a result, it will cause the invocation of class-level event
handlers only. For example:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">use</span> <span class="hljs-title">yii</span>\<span class="hljs-title">base</span>\<span class="hljs-title">Event</span>;

Event::on(Foo::className(), Foo::EVENT_HELLO, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$event</span>)</span> </span>{
    <span class="hljs-keyword">echo</span> <span class="hljs-variable">$event</span>-&gt;sender;  <span class="hljs-comment">// displays "app\models\Foo"</span>
});

Event::trigger(Foo::className(), Foo::EVENT_HELLO);
</code></pre>
<p>Note that, in this case, <code>$event-&gt;sender</code> refers to the name of the class triggering the event instead of an object instance.</p>
<blockquote class="note"><p><strong>Note: </strong>Because a class-level handler will respond to an event triggered by any instance of that class, or any child
  classes, you should use it carefully, especially if the class is a low-level base class, such as <a href="./yii-base-object.html">yii\base\Object</a>.</p>
</blockquote>
<p>To detach a class-level event handler, call <a href="./yii-base-event.html#off()-detail">yii\base\Event::off()</a>. For example:</p>
<pre><code class="hljs php language-php"><span class="hljs-comment">// detach $handler</span>
Event::off(Foo::className(), Foo::EVENT_HELLO, <span class="hljs-variable">$handler</span>);

<span class="hljs-comment">// detach all handlers of Foo::EVENT_HELLO</span>
Event::off(Foo::className(), Foo::EVENT_HELLO);
</code></pre>
<h2>Events using interfaces  <span id="interface-level-event-handlers"></span><a href="#interface-level-event-handlers" class="hashlink">&para;</a></h2><p>There is even more abstract way to deal with events. You can create a separated interface for the special event and
implement it in classes, where you need it.</p>
<p>For example we can create the following interface:</p>
<pre><code class="hljs php language-php"><span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">DanceEventInterface</span>
</span>{
    <span class="hljs-keyword">const</span> EVENT_DANCE = <span class="hljs-string">'dance'</span>;
}
</code></pre>
<p>And two classes, that implement it:</p>
<pre><code class="hljs php language-php"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">DanceEventInterface</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">meetBuddy</span><span class="hljs-params">()</span>
    </span>{
        <span class="hljs-keyword">echo</span> <span class="hljs-string">"Woof!"</span>;
        <span class="hljs-variable">$this</span>-&gt;trigger(DanceEventInterface::EVENT_DANCE);
    }
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Developer</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Component</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">DanceEventInterface</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">testsPassed</span><span class="hljs-params">()</span>
    </span>{
        <span class="hljs-keyword">echo</span> <span class="hljs-string">"Yay!"</span>;
        <span class="hljs-variable">$this</span>-&gt;trigger(DanceEventInterface::EVENT_DANCE);
    }
}
</code></pre>
<p>To handle the <code>EVENT_DANCE</code>, triggered by any of these classes, call <a href="./yii-base-event.html#on()-detail">Event::on()</a> and
pass the interface name as the first argument:</p>
<pre><code class="hljs php language-php">Event::on(<span class="hljs-string">'DanceEventInterface'</span>, DanceEventInterface::EVENT_DANCE, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$event</span>)</span> </span>{
    Yii::trace(<span class="hljs-variable">$event</span>-&gt;sender-&gt;className . <span class="hljs-string">' just danced'</span>); <span class="hljs-comment">// Will log that Dog or Developer danced</span>
})
</code></pre>
<p>You can trigger the event of those classes:</p>
<pre><code class="hljs php language-php">Event::trigger(DanceEventInterface::className(), DanceEventInterface::EVENT_DANCE);
</code></pre>
<p>But please notice, that you can not trigger all the classes, that implement the interface:</p>
<pre><code class="hljs php language-php"><span class="hljs-comment">// DOES NOT WORK</span>
Event::trigger(<span class="hljs-string">'DanceEventInterface'</span>, DanceEventInterface::EVENT_DANCE); <span class="hljs-comment">// error</span>
</code></pre>
<p>To detach event handler, call <a href="./yii-base-event.html#off()-detail">Event::off()</a>. For example:</p>
<pre><code class="hljs php language-php"><span class="hljs-comment">// detaches $handler</span>
Event::off(<span class="hljs-string">'DanceEventInterface'</span>, DanceEventInterface::EVENT_DANCE, <span class="hljs-variable">$handler</span>);

<span class="hljs-comment">// detaches all handlers of DanceEventInterface::EVENT_DANCE</span>
Event::off(<span class="hljs-string">'DanceEventInterface'</span>, DanceEventInterface::EVENT_DANCE);
</code></pre>
<h2>Global Events  <span id="global-events"></span><a href="#global-events" class="hashlink">&para;</a></h2><p>Yii supports a so-called <em>global event</em>, which is actually a trick based on the event mechanism described above.
The global event requires a globally accessible Singleton, such as the <a href="guide-structure-applications.html">application</a> instance itself.</p>
<p>To create the global event, an event sender calls the Singleton's <code>trigger()</code> method
to trigger the event, instead of calling the sender's own <code>trigger()</code> method. Similarly, the event handlers are attached to the event on the Singleton. For example:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">use</span> <span class="hljs-title">Yii</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">yii</span>\<span class="hljs-title">base</span>\<span class="hljs-title">Event</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">app</span>\<span class="hljs-title">components</span>\<span class="hljs-title">Foo</span>;

Yii::<span class="hljs-variable">$app</span>-&gt;on(<span class="hljs-string">'bar'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">(<span class="hljs-variable">$event</span>)</span> </span>{
    <span class="hljs-keyword">echo</span> get_class(<span class="hljs-variable">$event</span>-&gt;sender);  <span class="hljs-comment">// displays "app\components\Foo"</span>
});

Yii::<span class="hljs-variable">$app</span>-&gt;trigger(<span class="hljs-string">'bar'</span>, <span class="hljs-keyword">new</span> Event([<span class="hljs-string">'sender'</span> =&gt; <span class="hljs-keyword">new</span> Foo]));
</code></pre>
<p>A benefit of using global events is that you do not need an object when attaching a handler to the event
which will be triggered by the object. Instead, the handler attachment and the event triggering are both
done through the Singleton (e.g. the application instance).</p>
<p>However, because the namespace of the global events is shared by all parties, you should name the global events
wisely, such as introducing some sort of namespace (e.g. "frontend.mail.sent", "backend.mail.sent").</p>
        <div class="toplink"><a href="#" class="h1" title="go to top"><span class="glyphicon glyphicon-arrow-up"></a></div>
    </div>
</div>


</div>

<footer class="footer">
        <p class="pull-right"><small>Page generated on Sat, 09 Jul 2016 12:16:30 +0000</small></p>
    Powered by <a href="http://www.yiiframework.com/" rel="external">Yii Framework</a></footer>

<script type="text/javascript">jQuery(document).ready(function () {
    var shiftWindow = function () { scrollBy(0, -50) };
    if (location.hash) setTimeout(shiftWindow, 1);
    window.addEventListener("hashchange", shiftWindow);
var element = document.createElement("script");
element.src = "./jssearch.index.js";
document.body.appendChild(element);

var searchBox = $('#searchbox');

// search when typing in search field
searchBox.on("keyup", function(event) {
    var query = $(this).val();

    if (query == '' || event.which == 27) {
        $('#search-resultbox').hide();
        return;
    } else if (event.which == 13) {
        var selectedLink = $('#search-resultbox a.selected');
        if (selectedLink.length != 0) {
            document.location = selectedLink.attr('href');
            return;
        }
    } else if (event.which == 38 || event.which == 40) {
        $('#search-resultbox').show();

        var selected = $('#search-resultbox a.selected');
        if (selected.length == 0) {
            $('#search-results').find('a').first().addClass('selected');
        } else {
            var next;
            if (event.which == 40) {
                next = selected.parent().next().find('a').first();
            } else {
                next = selected.parent().prev().find('a').first();
            }
            if (next.length != 0) {
                var resultbox = $('#search-results');
                var position = next.position();

//              TODO scrolling is buggy and jumps around
//                resultbox.scrollTop(Math.floor(position.top));
//                console.log(position.top);

                selected.removeClass('selected');
                next.addClass('selected');
            }
        }

        return;
    }
    $('#search-resultbox').show();
    $('#search-results').html('<li><span class="no-results">No results</span></li>');

    var result = jssearch.search(query);

    if (result.length > 0) {
        var i = 0;
        var resHtml = '';

        for (var key in result) {
            if (i++ > 20) {
                break;
            }
            resHtml = resHtml +
            '<li><a href="' + result[key].file.u.substr(3) +'"><span class="title">' + result[key].file.t + '</span>' +
            '<span class="description">' + result[key].file.d + '</span></a></li>';
        }
        $('#search-results').html(resHtml);
    }
});

// hide the search results on ESC
$(document).on("keyup", function(event) { if (event.which == 27) { $('#search-resultbox').hide(); } });
// hide search results on click to document
$(document).bind('click', function (e) { $('#search-resultbox').hide(); });
// except the following:
searchBox.bind('click', function(e) { e.stopPropagation(); });
$('#search-resultbox').bind('click', function(e) { e.stopPropagation(); });

});</script></body>
</html>
